package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.json.JSONUtil;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.aliyun.teaopenapi.models.Config;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.CacheConstants;
import com.zzyl.dto.DeviceDto;
import com.zzyl.dto.DevicePageQueryDto;
import com.zzyl.entity.Device;
import com.zzyl.enums.BasicEnum;
import com.zzyl.enums.DeviceLocationTypeEnum;
import com.zzyl.enums.DevicePhysicalLocationTypeEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.DeviceMapper;
import com.zzyl.properties.AliIoTConfigProperties;
import com.zzyl.service.DeviceService;
import com.zzyl.utils.ObjectUtil;
import com.zzyl.utils.StringUtils;
import com.zzyl.vo.DeviceVo;
import com.zzyl.vo.ProductVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ffk
 * @date 2024/5/23 16:07
 */
@Service
@Slf4j
public class DeviceServiceImpl implements DeviceService {
    @Autowired
    private Client client;

    @Autowired
    private AliIoTConfigProperties aliIoTConfigProperties;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    DeviceMapper deviceMapper;

    /**
     * 同步数据
     */
    @Override
    public void syncProductList() {
        //请求参数
        QueryProductListRequest request = new QueryProductListRequest();
        //假设每页200，将小型养老院的产品全部获取
        request.setPageSize(200);
        request.setCurrentPage(1);
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());

        //调用第三方查询产品列表
        QueryProductListResponse response;
        try {
            response = client.queryProductList(request);
        } catch (Exception e) {
            //物联网接口 - 查询产品，调用失败
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }

        //判断，如果数据为空，则中断请求
        if(!response.getBody().success){
            //物联网接口 - 查看所有产品列表，调用失败
            throw new BaseException(BasicEnum.IOT_LIST_PRODUCT_ERROR);
        }

        //获取数据，存储到redis
        List<ProductVo> productVoList =
                response.getBody()
                        .getData()
                        .getList()
                        .getProductInfo()
                        .stream().map( p -> BeanUtil.toBean(p, ProductVo.class))
                        .collect(Collectors.toList());
        //存储到redis
        redisTemplate.opsForValue().set(CacheConstants.ALL_PRODUCT_KEY,
                JSONUtil.toJsonStr(productVoList));
    }

    @Override
    public List<ProductVo> allProduct() {
        //从缓存中获取数据
        String jsonStr = redisTemplate.opsForValue().get(CacheConstants.ALL_PRODUCT_KEY);
        //如果为空，返回空集合
        if(StringUtils.isEmpty(jsonStr)){
            return Collections.emptyList();
        }
        //转换数据，并返回
        return JSONUtil.toList(jsonStr,ProductVo.class);
    }


    //分页
    @Override
    public PageResponse<DeviceVo> getAllDevice(DevicePageQueryDto devicePageQueryDto) {
        PageHelper.startPage(devicePageQueryDto.getPageNum(),devicePageQueryDto.getPageSize());
        List<DeviceVo> deviceVoList =  deviceMapper.getAllDeviceByPage(devicePageQueryDto);
        Page<DeviceVo> deviceVoPage= (Page<DeviceVo>) deviceVoList;
        return PageResponse.of(deviceVoPage, DeviceVo.class);
    }

    @Override
    public void registerDevice(DeviceDto deviceDto) {
        String deviceName = deviceDto.getDeviceName();//当前设备名称
        Long countDdevice = deviceMapper.countDeviceByName(deviceName);
        if (countDdevice > 0) {
            throw new BaseException(BasicEnum.DEVICE_NAME_EXIST);
        }

//        Config config=new Config()
//                .setAccessKeyId(aliIoTConfigProperties.getAccessKeyId())
//                .setAccessKeySecret(aliIoTConfigProperties.getAccessKeySecret())
//                .setRegionId(aliIoTConfigProperties.getRegionId());

        RegisterDeviceRequest registerDeviceRequest = deviceDto.getRegisterDeviceRequest();
        registerDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
//        registerDeviceRequest.setProductKey(deviceDto.getProductKey());
        RegisterDeviceResponse registerDeviceResponse = null;

        try {
//            Client client=new Client(config);
//            PubRequest pubRequest=new PubRequest()
//                    .setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
//            PubResponse res = client.pub(pubRequest);
            registerDeviceResponse = client.registerDevice(registerDeviceRequest);

        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }

        if (registerDeviceResponse == null || !registerDeviceResponse.getBody().success) {
            //物联网接口 - 注册设备，调用失败
            throw new RuntimeException(registerDeviceResponse.getBody().getErrorMessage());
        }

        Device device = BeanUtil.toBean(deviceDto, Device.class);
        device.setIotId(registerDeviceResponse.getBody().getData().getIotId());
        log.info("设备注册成功，设备信息：{}", device);

        //产品名称
        QueryProductRequest queryProductRequest = new QueryProductRequest();
        queryProductRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        queryProductRequest.setProductKey(deviceDto.getProductKey());
        QueryProductResponse queryProductResponse;

        try {
            queryProductResponse = client.queryProduct(queryProductRequest);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        log.info("查询产品信息成功，产品信息：{}", queryProductResponse);

        //设置产品名称
        if (queryProductResponse.getBody().success) {
            device.setProductName(queryProductResponse.getBody().getData().productName);
        }

        if (device.getLocationType().equals(DeviceLocationTypeEnum.PORTABLE_DEVICE.getOrdinal())) {
            device.setPhysicalLocationType(DevicePhysicalLocationTypeEnum.ELDER.getOrdinal());
        }

        //保存设备
        try {
            deviceMapper.insertSelective(device);
            log.info("设备保存成功，设备信息：{}", device);
        } catch (Exception e) {
            log.error(e.getMessage());
            //删除iot中的设备数据
            DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest();
            deleteDeviceRequest.setDeviceName(device.getDeviceName());
            deleteDeviceRequest.setIotId(device.getIotId());
            deleteDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
            deleteDeviceRequest.setProductKey(device.getProductKey());

            try {
                client.deleteDevice(deleteDeviceRequest);
            } catch (Exception ex) {
                throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
            }
            throw new BaseException(BasicEnum.RE_SELECT_PRODUCT);
        }
    }

    @Override
    public DeviceVo queryDeviceDetail(QueryDeviceDetailRequest request) {

        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());//实例ID
        QueryDeviceDetailResponse response;
        try {
             response = client.queryDeviceDetail(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }

        if(!response.getBody().getSuccess()){
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }

        DeviceVo deviceVo = deviceMapper.selectByIotId(response.getBody().getData().getIotId());

        QueryDeviceDetailResponseBody.QueryDeviceDetailResponseBodyData data = response.getBody().getData();
        BeanUtil.copyProperties(data,deviceVo, CopyOptions.create().ignoreNullValue());


        return deviceVo;

    }

    //1.6 查询指定设备的物模型运行状态
    @Override
    public QueryDevicePropertyStatusResponseBody.QueryDevicePropertyStatusResponseBodyData queryDevicePropertyStatus(QueryDevicePropertyStatusRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDevicePropertyStatusResponse response;
        try {
             response = client.queryDevicePropertyStatus(request);
        }catch (Exception e){
            throw  new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }

        if(!response.getBody().getSuccess()){
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }

        return response.getBody().getData();
    }

    @Override
    public QueryThingModelPublishedResponseBody.QueryThingModelPublishedResponseBodyData queryThingModelPublished(QueryThingModelPublishedRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryThingModelPublishedResponse response;
        try {
             response = client.queryThingModelPublished(request);
        }catch (Exception e){
            throw  new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }

        if(!response.getBody().getSuccess()){
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }

        log.info("查询物模型成功，看一下物模型信息：{}",response.getBody().getData());

        return response.getBody().getData();
    }


    //修改更新
    @Override
    public void updateDevice(DeviceDto deviceDto) {

        //检验数据库是否存在设备
        Device dbDevice = deviceMapper.selectByPrimaryKey(deviceDto.getId());
        if (ObjectUtil.isEmpty(dbDevice)) {
            throw new BaseException(BasicEnum.DEVICE_NOT_EXIST);
        }

        //调用物联网接口，更新云服务设备信息
        BatchUpdateDeviceNicknameRequest request = new BatchUpdateDeviceNicknameRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo nicknameInfo = BeanUtil.toBean(deviceDto, BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo.class);
        request.setDeviceNicknameInfo(Lists.newArrayList(nicknameInfo));
        BatchUpdateDeviceNicknameResponse response;
        try {
            response = client.batchUpdateDeviceNickname(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_BATCH_UPDATE_DEVICE_ERROR);
        }
        if (ObjectUtil.notEqual(Boolean.TRUE, response.getBody().getSuccess())) {
            throw new BaseException(BasicEnum.IOT_BATCH_UPDATE_DEVICE_ERROR);
        }


        Device device = BeanUtil.toBean(deviceDto, Device.class);

        if (device.getLocationType().equals(DeviceLocationTypeEnum.PORTABLE_DEVICE.getOrdinal())) {
            device.setPhysicalLocationType(DevicePhysicalLocationTypeEnum.ELDER.getOrdinal());
        }

        //更新数据库中设备信息
        try {
            deviceMapper.updateDevice(device);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.RE_SELECT_PRODUCT);
        }




    }

    @Override
    public void deleteDevice(DeleteDeviceRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());

        DeleteDeviceResponse response;
        try {
            response = client.deleteDevice(request);
        } catch (Exception e) {
            throw  new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
        }

        if(!response.getBody().getSuccess()){
            throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
        }

        deviceMapper.deleteDeviceById(request.getIotId());




    }


}
